package utils

import (
	"bytes"
	"crypto/md5"
	"crypto/rand"
	"encoding/hex"
	"encoding/json"
	"html"
	"math/big"
	"reflect"
	"regexp"
	"strings"
)


// CreateJsonUseNum  解决json精度问题
func CreateJsonUseNum(source string) map[string]interface{} {
	data := map[string]interface{}{}
	dec := json.NewDecoder(strings.NewReader(source))
	dec.UseNumber()
	_ = dec.Decode(&data)
	return data
}

// IsMobile  判断请求是否为手机端
func IsMobile(userAgent string) bool {
	if len(userAgent) == 0 {
		return false
	}
	isMobile := false
	mobileKeywords := []string{"Mobile", "Android", "Silk/", "Kindle",
		"BlackBerry", "Opera Mini", "Opera Mobi"}
	for i := 0; i < len(mobileKeywords); i++ {
		if strings.Contains(userAgent, mobileKeywords[i]) {
			isMobile = true
			break
		}
	}
	return isMobile
}

// MD5  md5签名
func MD5(text string) string {
	ctx := md5.New()
	ctx.Write([]byte(text))
	return hex.EncodeToString(ctx.Sum(nil))
}

// TrimHtml 过滤html标签
func TrimHtml(src string) string {
	src = html.UnescapeString(src)
	//将HTML标签全转换成小写
	re, _ := regexp.Compile("\\<[\\S\\s]+?\\>")
	src = re.ReplaceAllStringFunc(src, strings.ToLower)
	//去除STYLE
	re, _ = regexp.Compile("\\<style[\\S\\s]+?\\</style\\>")
	src = re.ReplaceAllString(src, "")
	//去除SCRIPT
	re, _ = regexp.Compile("\\<script[\\S\\s]+?\\</script\\>")
	src = re.ReplaceAllString(src, "") //去除SCRIPT
	//去除所有尖括号内的HTML代码，并换成换行符
	re, _ = regexp.Compile("\\<[\\S\\s]+?\\>")
	src = re.ReplaceAllString(src, "\n")
	//src = StripTags(src)
	//去除连续的换行符
	re, _ = regexp.Compile("\\s{2,}")
	src = re.ReplaceAllString(src, "\n")
	return strings.TrimSpace(src)
}

// ToSlice 将interface类型的slice 转化为slice
func ToSlice(arr interface{}) []interface{} {
	v := reflect.ValueOf(arr)
	if v.Kind() != reflect.Slice {
		panic("to slice arr not slice")
	}
	l := v.Len()
	ret := make([]interface{}, l)
	for i := 0; i < l; i++ {
		ret[i] = v.Index(i).Interface()
	}
	return ret
}

// Struct2Map 结构体转为map
func Struct2Map(obj interface{}) map[string]interface{} {
	t := reflect.TypeOf(obj)
	v := reflect.ValueOf(obj)
	var data = make(map[string]interface{})
	for i := 0; i < t.NumField(); i++ {
		data[t.Field(i).Name] = v.Field(i).Interface()
	}
	return data
}

// CreateRandomString  随机数
func CreateRandomString(len int) string {
	var container string
	var str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
	b := bytes.NewBufferString(str)
	length := b.Len()
	bigInt := big.NewInt(int64(length))
	for i := 0; i < len; i++ {
		randomInt, _ := rand.Int(rand.Reader, bigInt)
		container += string(str[randomInt.Int64()])
	}
	return container
}

// SliceDupData 获取slice中重复元素
func SliceDupData(arr []int) []int {
	num := make(map[int]bool)
	result := make([]int, 0, len(arr))
	for _, v := range arr {
		if !num[v] {
			num[v] = true
		} else {
			result = append(result, v)
		}
	}
	return result
}

// InSliceOrNot 判断目标值是否在数组中
func InSliceOrNot(target int, dup []int) bool {
	res := false
	for _, data := range dup {
		if data == target {
			res = true
		}
	}
	return res
}

// CutLength 截取指定长度的字符串
func CutLength(s string, length int) string {
	if len(s) < length {
		return s
	}
	return s[:length]
}
